package com.molichuxing.gateway.bff.orders.services.impl;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.molichuxing.framework.exception.BizException;
import com.molichuxing.framework.utils.DateUtil;
import com.molichuxing.framework.utils.DingTalkUtil;
import com.molichuxing.framework.utils.EmailUtil;
import com.molichuxing.gateway.bff.orders.convertor.Convert;
import com.molichuxing.gateway.bff.orders.entity.request.modify.ReportModifyVo;
import com.molichuxing.gateway.bff.orders.entity.request.modify.ReturnCarModifyVo;
import com.molichuxing.gateway.bff.orders.entity.response.CheckReportVo;
import com.molichuxing.gateway.bff.orders.entity.response.ReportVo;
import com.molichuxing.gateway.bff.orders.entity.response.ReturnCarResultVo;
import com.molichuxing.gateway.bff.orders.services.OrderReturnBffService;
import com.molichuxing.services.business.dto.request.create.MessageCenterCreateBizDto;
import com.molichuxing.services.business.dto.request.modify.OrderModifyBizDto;
import com.molichuxing.services.business.dto.request.modify.ReportModifyBizDto;
import com.molichuxing.services.business.dto.response.OrderBizDto;
import com.molichuxing.services.business.dto.response.OrderExclusivelBizDto;
import com.molichuxing.services.business.dto.response.OrderSubscribeBizDto;
import com.molichuxing.services.business.dto.response.PdiCheckBizDto;
import com.molichuxing.services.business.dto.response.StoreBizDto;
import com.molichuxing.services.business.dto.response.VehicleNameBizDto;
import com.molichuxing.services.business.service.CarBizService;
import com.molichuxing.services.business.service.CarCheckBizService;
import com.molichuxing.services.business.service.MessageCenterBizService;
import com.molichuxing.services.business.service.OrderBizService;
import com.molichuxing.services.business.service.OrderRenegeBizService;
import com.molichuxing.services.business.service.OrderReturnBizService;
import com.molichuxing.services.business.service.OrderSubscribeBizService;
import com.molichuxing.services.business.service.SmsBizService;
import com.molichuxing.services.business.service.StoreBizService;
import com.molichuxing.services.business.service.VehicleBizService;
import com.molichuxing.services.contants.OrderStatusConst;
import com.molichuxing.services.infrastructure.dto.request.create.IovFenceBindingCreateDto;
import com.molichuxing.services.infrastructure.dto.request.create.MessageCenterCreateDto;
import com.molichuxing.services.infrastructure.dto.request.create.MessageContentCreateDto;
import com.molichuxing.services.infrastructure.dto.request.create.NotifyPushCreateDto;
import com.molichuxing.services.infrastructure.dto.response.CarDto;
import com.molichuxing.services.infrastructure.dto.response.CheckDto;
import com.molichuxing.services.infrastructure.dto.response.ContractDto;
import com.molichuxing.services.infrastructure.dto.response.MessageTemplateDto;
import com.molichuxing.services.infrastructure.dto.response.OrderSubscribeDto;
import com.molichuxing.services.infrastructure.dto.response.OrderSubscribeSettlementDto;
import com.molichuxing.services.infrastructure.dto.response.RiskEmailDto;
import com.molichuxing.services.infrastructure.dto.response.UserDto;
import com.molichuxing.services.infrastructure.service.CarService;
import com.molichuxing.services.infrastructure.service.CheckService;
import com.molichuxing.services.infrastructure.service.ContractService;
import com.molichuxing.services.infrastructure.service.FenceStoreStockService;
import com.molichuxing.services.infrastructure.service.IovCarService;
import com.molichuxing.services.infrastructure.service.IovFenceService;
import com.molichuxing.services.infrastructure.service.MaintenanceService;
import com.molichuxing.services.infrastructure.service.MessageTemplateService;
import com.molichuxing.services.infrastructure.service.NotifyPushService;
import com.molichuxing.services.infrastructure.service.OrderSubscribeService;
import com.molichuxing.services.infrastructure.service.OrderSubscribeSettlementService;
import com.molichuxing.services.infrastructure.service.RiskEmailService;
import com.molichuxing.services.infrastructure.service.StockCarService;
import com.molichuxing.services.infrastructure.service.UserService;
import com.molichuxing.services.property.CarCheckTypeEnum;
import com.molichuxing.services.property.ContractTypeEnum;
import com.molichuxing.services.property.FenceStoreStockTypeEnum;
import com.molichuxing.services.property.MessageCenterStatusEnum;
import com.molichuxing.services.property.MessageCenterTypeEnum;
import com.molichuxing.services.property.OrderExclusivelStatusEnum;
import com.molichuxing.services.property.OrderPaymentMethodEnum;
import com.molichuxing.services.property.OrderStatusFlowModifiedTypeEnum;
import com.molichuxing.services.property.OrderSubscribeStatusEnum;
import com.molichuxing.services.property.OrderTypeEnum;
import com.molichuxing.services.property.RiskEmailReceiveTypeEnum;
import com.molichuxing.services.property.RiskEmailTypeEnum;
import com.molichuxing.services.property.SmsTemplateEnum;
import com.molichuxing.services.property.StockCarCarStatusEnum;

/**
 * 订单还车bff
 *
 * @author zoumingyu
 * @date 2019年9月19日
 */
@Service("orderReturnBffService")
public class OrderReturnBffServiceImpl implements OrderReturnBffService {
    private static final Logger logger = LoggerFactory.getLogger(OrderReturnBffServiceImpl.class);

	@Value("${profiles.active}")
	private String ACTIVE;

	@Value("${profiles.active.explain}")
	private String ACTIVE_EXPLAIN;

	@Value("${email.account}")
	private String EMAIL_ACCOUNT;

	@Value("${email.password}")
	private String EMAIL_PASSWORD;

	@Resource
	private OrderBizService orderBizService;

    @Resource
    private OrderSubscribeService orderSubscribeService;

    @Resource
    private OrderSubscribeSettlementService orderSubscribeSettlementService;

    @Resource
    private OrderSubscribeBizService orderSubscribeBizService;

	@Resource
	private OrderReturnBizService orderReturnBizService;

	@Resource
	private OrderRenegeBizService orderRenegeBizService;

    @Resource
	private CheckService checkService;

    @Resource
	private CarCheckBizService carCheckBizService;

	@Resource
	private CarService carService;

	@Resource
	private CarBizService carBizService;

	@Resource
	private StoreBizService storeBizService;

	@Resource
	private IovCarService iovCarService;

	@Resource
	private IovFenceService iovFenceService;

    @Resource
	private ContractService contractService;

	@Resource
	private StockCarService stockCarService;

	@Resource
	private UserService userService;

	@Resource
	private SmsBizService smsBizService;

	@Resource
	private MessageTemplateService messageTemplateService;

	@Resource
	private NotifyPushService notifyPushService;

	@Resource
	private VehicleBizService vehicleBizService;

	@Resource
	private MessageCenterBizService messageCenterBizService;

	@Resource
	private RiskEmailService riskEmailService;

	@Resource
	private MaintenanceService maintenanceService;

    @Resource
    private FenceStoreStockService fenceStoreStockService;

    /**
     * 验车报告确认
     *
     * @param modifyVo
     * @return
     * @throws BizException
     * @throws Exception
     */
    @Override
    public ReportVo modifyReportConfirm(ReportModifyVo modifyVo) throws BizException, Exception {
        Long orderCode = modifyVo.getOrderCode();
        List<CheckDto> checkList = checkService.getCheckByOrderCode(orderCode);
        if (null == checkList || checkList.size() < 1) {
            throw new BizException("验车报告不存在");
        }

        ReportVo result = null;
        // 判断
        if (!modifyVo.getType() && StringUtils.isBlank(modifyVo.getRemark())) {
            logger.error("[modifyReportConfirm]验车报告确认不同意，备注不能为空");
            throw new BizException("验车报告确认不同意，备注不能为空");
        }
        // 根据订单号查询状态订单信息
        OrderSubscribeDto orderSubscribeDto = orderSubscribeService.getOrderSubscribe(modifyVo.getOrderCode());
        if (orderSubscribeDto == null) {
            logger.error("[modifyReportConfirm]结算订单({})不存在", modifyVo.getOrderCode());
            throw new BizException("订单不存在");
        } else if (!OrderSubscribeStatusEnum.RETURN_UNCONFIRM.equals(orderSubscribeDto.getOrderStatus())) {
            logger.error("[modifyReportConfirm]订单({})不是用户待确认状态", modifyVo.getOrderCode());
            throw new BizException("订单异常");
        }
        result = new ReportVo();

        OrderModifyBizDto orderModifyDto = new OrderModifyBizDto();
        orderModifyDto.setOrderCode(modifyVo.getOrderCode());
        orderModifyDto.setPreOrderStatus(orderSubscribeDto.getOrderStatus());
        orderModifyDto.setModifiedType(OrderStatusFlowModifiedTypeEnum.C_USER);
        // 修改订单状态
        if (modifyVo.getType()) {
            // 同意
            OrderSubscribeSettlementDto orderSubscribeSettlementDto = orderSubscribeSettlementService
                    .getOrderSubscribeSettlement(modifyVo.getOrderCode());
            if (orderSubscribeSettlementDto == null) {
                // 无结算信息，直接结束
                orderModifyDto.setOrderStatus(OrderSubscribeStatusEnum.RETURN_FINISH);
                result.setResult(0);
            } else if (orderSubscribeSettlementDto.getTotalFee() == null
                    || orderSubscribeSettlementDto.getTotalFee().compareTo(BigDecimal.ZERO) == 0) {
                // 结算金额为0，直接结束
                orderModifyDto.setOrderStatus(OrderSubscribeStatusEnum.RETURN_FINISH);
                result.setResult(0);
            } else {
                // 有结算
                orderModifyDto.setOrderStatus(OrderSubscribeStatusEnum.RETURN_UNPAID);
                result.setOrderCode(orderSubscribeDto.getOrderCode());
                result.setResult(1);
            }
        } else {
            // 不同意
            orderModifyDto.setOrderStatus(OrderSubscribeStatusEnum.RETURN_INTERVENE);
            result.setResult(0);
        }
		if (!orderReturnBizService.modifyReportConfirm(orderModifyDto)) {
            logger.error("[modifyReportConfirm]订阅订单({})修改状态失败", modifyVo.getOrderCode());
            throw new BizException("订单异常");
        }

        // 修改检验状态
        ReportModifyBizDto reportModifyBizDto = Convert.toReportModifyBizDto(modifyVo);
        if (!carCheckBizService.modifyReportConfirm(reportModifyBizDto)) {
            logger.error("[modifyReportConfirm]订单({})修改车辆检验状态失败", modifyVo.getOrderCode());
            throw new BizException("车辆检验信息异常");
        }

		if (!modifyVo.getType()) {
			// 不同意，发送提醒
			pushMsgToService(orderSubscribeDto);
		}

        return result;
    }

	private void pushMsgToService(OrderSubscribeDto orderSubscribeDto) {
		try {
			List<RiskEmailDto> riskEmailDtos = riskEmailService.getByType(RiskEmailTypeEnum.PDI_DISPUTES.getValue(),
					null);
			if (riskEmailDtos == null || riskEmailDtos.isEmpty()) {
				return;
			}

			List<String> emailRecipients = new ArrayList<>();
			List<String> emailCopys = new ArrayList<>();
			String dingTalkUrl = null;
			for (RiskEmailDto riskEmailDto : riskEmailDtos) {
				if (riskEmailDto.getReceiveType() == RiskEmailReceiveTypeEnum.EMAIL_RECIPIENT.getValue()) {
					emailRecipients.add(riskEmailDto.getEmail());
				} else if (riskEmailDto.getReceiveType() == RiskEmailReceiveTypeEnum.EMAIL_COPY.getValue()) {
					emailCopys.add(riskEmailDto.getEmail());
				} else if (riskEmailDto.getReceiveType() == RiskEmailReceiveTypeEnum.DINGTALK_WEBHOOK.getValue()) {
					dingTalkUrl = riskEmailDto.getEmail();
				}
			}

			// 查询车辆信息
			CarDto carDto = carService.getCarById(orderSubscribeDto.getCarId());
			if (!emailRecipients.isEmpty()) {
				// 发送邮件
				String subject = "PDI检验争议处理提醒";
				String content = "亲，有一PDI检验争议处理车辆（" + carDto.getLicencePlate() + "），请尽快登录系统跟进处理。";
				EmailUtil.sendMail(EMAIL_ACCOUNT, EMAIL_PASSWORD, subject, content, emailRecipients,
						(emailCopys.isEmpty() ? null : emailCopys));
			}
			if (StringUtils.isNotBlank(dingTalkUrl)) {
				String content = "PDI检验争议处理车辆（" + carDto.getLicencePlate() + "），请尽快登录系统跟进处理。";
				// 发送钉钉
				DingTalkUtil.execute(dingTalkUrl, content);
			}
		} catch (Exception e) {
			String msg = "订单(" + orderSubscribeDto.getOrderCode() + ")PDI待争议处理发送信息给客服异常：";
			logger.error(msg, e);
		}

	}

	/**
	 * 验车报告查看
	 *
	 * @param orderCode
	 * @return
	 */
    @Override
    public CheckReportVo getCheckReport(Long orderCode) {
        PdiCheckBizDto checkReport = carCheckBizService.getCheckReport(orderCode);
        OrderSubscribeSettlementDto orderSubscribeSettlement = orderSubscribeSettlementService.getOrderSubscribeSettlement(orderCode);
        List<ContractDto> contract = contractService.getContractByOrderCode(orderCode, ContractTypeEnum.MILEAGE_BAG_RETURN_CAR.getValue());

        CheckReportVo checkReportVo = Convert.toCheckReportVo(checkReport, orderSubscribeSettlement);
        if (contract != null && contract.size() > 0) {
            ContractDto contractDto = contract.get(0);
            String contractPath = contractDto.getContractPath();
            checkReportVo.setDomainPath(contractPath);
        }

        return checkReportVo;
    }

	/**
	 * 订单还车
	 * 
	 * @param modifyVo
	 * @return
	 */
	@Override
	public ReturnCarResultVo modifyReturnCar(ReturnCarModifyVo modifyVo) throws BizException, Exception {
		ReturnCarResultVo result = new ReturnCarResultVo();
		// 查询订单信息
		OrderBizDto order = orderBizService.getOrder(modifyVo.getOrderCode());
		if (order == null) {
			logger.error("[modifyReturnCar]订单({})还车失败，订单不存在", modifyVo.getOrderCode());
			result.failure("还车失败！");
			return result;
		}
		// 判断订单类型
		if (OrderTypeEnum.EXCLUSIVEL.equals(order.getType())) {
			// 专属里程订单
			result = modifyExclusivelReturnCar(modifyVo, order, result);
		} else if (OrderTypeEnum.SUBSCRIBE.equals(order.getType())) {
			// 订阅里程订单
			result = modifySubscribeReturnCar(modifyVo, result);
		}else {
			logger.error("[modifyReturnCar]订单({})还车失败，订单类型({})错误", modifyVo.getOrderCode(), order.getType());
			result.failure("还车失败！");
		}
		
		return result;
	}

	/**
	 * 专属订单还车
	 * 
	 * @param modifyVo
	 * @param order
	 * @param result
	 * @return
	 * @throws Exception
	 */
	private ReturnCarResultVo modifyExclusivelReturnCar(ReturnCarModifyVo modifyVo, OrderBizDto order,
			ReturnCarResultVo result) throws Exception {
		OrderExclusivelBizDto orderExclusivelBizDto = (OrderExclusivelBizDto) order;
		if (!OrderExclusivelStatusEnum.RENEGE_ACCEPTED.equals(orderExclusivelBizDto.getOrderStatus())) {
			logger.error("[modifyExclusivelReturnCar]订单({})还车失败，不是退租受理状态", modifyVo.getOrderCode());
			result.failure("还车失败！");
			return result;
		} else if (orderExclusivelBizDto.getCarId() == null || orderExclusivelBizDto.getCarId() <= 0) {
			logger.error("[modifyExclusivelReturnCar]订单({})还车失败，该订单未提车", modifyVo.getOrderCode());
			result.failure("还车失败！");
			return result;
		}

		// 查询门店信息
		StoreBizDto store = storeBizService.getStoreDetailsByCpu(modifyVo.getDeviceNum());
		// 验证门店信息
		if (store == null) {
			logger.error("[modifyExclusivelReturnCar]订单({})还车失败，设备({})关联门店不存在", modifyVo.getOrderCode(),
					modifyVo.getDeviceNum());
			result.failure("还车失败！");
			return result;
		}
		if (!orderExclusivelBizDto.getPlaceStoreId().equals(store.getStoreId())) {
			logger.error("[modifyExclusivelReturnCar]订单({})还车失败，设备({})关联门店({})不是订单下单门店({})", modifyVo.getOrderCode(),
					modifyVo.getDeviceNum(), store.getStoreId(), orderExclusivelBizDto.getPlaceStoreId());
			result.failure("还车失败！");
			return result;
		}
		// 查询车辆信息
		CarDto carDto = carService.getCarById(modifyVo.getCarId());
		if (carDto == null) {
			logger.error("[modifyExclusivelReturnCar]订单({})还车失败，车辆({})不存在", modifyVo.getOrderCode(),
					modifyVo.getCarId());
			result.failure("还车失败！");
			return result;
		}

		// 判断车辆是否在门店围栏，绑定围栏，修改车辆信息、保存车辆交接单信息、新增pdi检验信息，修改库存信息，修改保养信息
		if (!checkModifyCar(modifyVo, carDto, store, CarCheckTypeEnum.NEW_CHECK)) {
			result.failure("还车失败！");
			DingTalkUtil.exceptionSend(ACTIVE_EXPLAIN + "还车失败");
			return result;
		}

		// 保存还车表信息，修改订单信息，修改排期信息
		if (!orderRenegeBizService.modifyReturnCar(Convert.toOrderReturnCarModifyBizDto(modifyVo, store))) {
			logger.error("[modifyExclusivelReturnCar]退租修改订单信息失败");
			DingTalkUtil.exceptionSend(ACTIVE_EXPLAIN + "退租修改车辆信息成功，修改订单信息失败");
			result.failure("还车失败，请联系客服！");
			return result;
		}
		result.success("退租车辆归还成功，祝您生活愉快！");
		result.setExplain(
				"为保证您的剩余钱款快速到账，请协同工作人员和车务人员对车辆质损评估结果进行线下确认，在您确认后将进入退租的退款结算流程，扫描下方二维码上传退款账号的信息。或在茉莉科技APP进行退租账号信息的填写。");

		// 发送消息
		pushMsg(orderExclusivelBizDto, carDto, store);

		return result;
	}

	/**
	 * 订阅订单还车
	 * 
	 * @param modifyVo
	 * @param result
	 * @return
	 * @throws Exception
	 */
	private ReturnCarResultVo modifySubscribeReturnCar(ReturnCarModifyVo modifyVo, ReturnCarResultVo result)
			throws Exception {
		OrderSubscribeDto orderSubscribeDto = orderSubscribeService.getOrderSubscribe(modifyVo.getOrderCode());
		// 验证订单信息
		if (orderSubscribeDto == null) {
			logger.error("[modifySubscribeReturnCar]订单({})还车失败，订单不存在", modifyVo.getOrderCode());
			result.failure("还车失败！");
			return result;
		} else if (!OrderSubscribeStatusEnum.TRADE_USE.equals(orderSubscribeDto.getOrderStatus())) {
			logger.error("[modifySubscribeReturnCar]订单({})还车失败，不是用车中状态", modifyVo.getOrderCode());
			result.failure("还车失败！");
			return result;
		} else if (orderSubscribeDto.getIsHaveSuborder()) {
			logger.error("[modifySubscribeReturnCar]订单({})还车失败，存在续订单", modifyVo.getOrderCode());
			result.failure("还车失败！");
			return result;
		}
		// 查询门店信息
		StoreBizDto store = storeBizService.getStoreDetailsByCpu(modifyVo.getDeviceNum());
		// 验证门店信息
		if (store == null) {
			logger.error("[modifySubscribeReturnCar]订单({})还车失败，设备({})关联门店不存在", modifyVo.getOrderCode(),
					modifyVo.getDeviceNum());
			result.failure("还车失败！");
			return result;
		}
		if (!orderSubscribeDto.getPlaceStoreId().equals(store.getStoreId())) {
			logger.error("[modifySubscribeReturnCar]订单({})还车失败，设备({})关联门店({})不是订单下单门店({})", modifyVo.getOrderCode(),
					modifyVo.getDeviceNum(), store.getStoreId(),
					orderSubscribeDto.getPlaceStoreId());
			result.failure("还车失败！");
			return result;
		}
		// 查询车辆信息
		CarDto carDto = carService.getCarById(modifyVo.getCarId());
		if (carDto == null) {
			logger.error("[modifySubscribeReturnCar]订单({})还车失败，车辆({})不存在", modifyVo.getOrderCode(),
					modifyVo.getCarId());
			result.failure("还车失败！");
			return result;
		}
		// 查询车辆当前里程
		Integer currentMileage = iovCarService.getCurrentMileage(carDto.getVin());
		// 检验里程信息
		if ((currentMileage - 100) > modifyVo.getMileage()) {
			logger.error("[modifySubscribeReturnCar]订单({})还车失败，车辆里程信息异常，现在里程({})大于还车里程({})", modifyVo.getOrderCode(),
					currentMileage, modifyVo.getMileage());
			result.failure("还车失败！");
			return result;
		}
		// 判断车辆是否在门店围栏，绑定围栏，修改车辆信息、保存车辆交接单信息、新增pdi检验信息，修改库存信息，修改保养信息
		if (!checkModifyCar(modifyVo, carDto, store, CarCheckTypeEnum.PDI)) {
			result.failure("还车失败！");
			DingTalkUtil.exceptionSend(ACTIVE_EXPLAIN + "还车失败");
			return result;
		}

		// 保存还车表信息，修改订单信息，新增结算信息
		if (!orderReturnBizService.modifyReturnCar(Convert.toOrderReturnCarModifyBizDto(modifyVo, store))) {
			logger.error("[modifySubscribeReturnCar]还车修改订单信息失败");
			DingTalkUtil.exceptionSend(ACTIVE_EXPLAIN + "还车修改车辆信息成功，修改订单信息失败");
			result.failure("还车失败，请联系客服！");
			return result;
		}
		result.success("还车完成，祝您生活愉快！");

		// 发送消息
		pushMsg(orderSubscribeDto, carDto, store);

		return result;
	}

	/**
	 * 还车发送消息
	 * 
	 * @param orderSubscribeDto
	 * @param carDto
	 * @param store
	 */
	private void pushMsg(OrderSubscribeDto orderSubscribeDto, CarDto carDto, StoreBizDto store) {
		try {
			// 查询用户信息
			UserDto userDto = userService.getUser(orderSubscribeDto.getUserId());
			JSONObject json = new JSONObject();
			// 订单
			json.put("order", orderSubscribeDto.getOrderCode());
			// 发送短信
			try {
				smsBizService.sendMessage(userDto.getPhone(), SmsTemplateEnum.ORDER_RETURN_SMS.getValue(),
						json.toJSONString(), null);
			} catch (Exception e) {
				logger.error("还车(" + orderSubscribeDto.getOrderCode() + ")完成发送短信异常", e);
			}
			// 发送推送
			MessageTemplateDto messageTemplateDto = null;
			try {
				messageTemplateDto = messageTemplateService.getByKey("push_return_car_success");
				String body = messageTemplateDto.getBody().replace("${orderCode}",
						orderSubscribeDto.getOrderCode() + "");
				// 推送
				NotifyPushCreateDto notifyPush = new NotifyPushCreateDto(Arrays.asList(userDto.getPhone()),
						messageTemplateDto.getSubject(), messageTemplateDto.getSubject(), body, body, null, "");
				notifyPushService.notifyPushByAlias(notifyPush);
			} catch (Exception e) {
				logger.error("还车(" + orderSubscribeDto.getOrderCode() + ")完成发送短信异常", e);
			}

			// 查询车型信息
			VehicleNameBizDto vehicleName = vehicleBizService.getCarByModel(orderSubscribeDto.getVehicleId());
			String goodsName = vehicleName.getModelName() + " " + orderSubscribeDto.getTransportTime() + "个月/"
					+ orderSubscribeDto.getBaseMileage() + "公里, " + orderSubscribeDto.getPackageMileage() + "公里";

			// 保存消息
			MessageCenterCreateBizDto messageCenterCreateBizDto = new MessageCenterCreateBizDto();
			MessageCenterCreateDto messageCenterCreateDto = new MessageCenterCreateDto();
			messageCenterCreateDto.setUserId(userDto.getId());
			messageCenterCreateDto.setTitle("还车成功通知");
			messageCenterCreateDto.setMessage("您的订单车辆已归还，祝您生活愉快！");
			messageCenterCreateDto.setType(MessageCenterTypeEnum.CARRIAGE_SUCCESS_NOTICE.getValue());
			messageCenterCreateDto.setStatus(MessageCenterStatusEnum.UNREAD.getValue());
			List<MessageContentCreateDto> messageContentCreateDtos = new ArrayList<>();
			messageContentCreateDtos.add(new MessageContentCreateDto("订单号", orderSubscribeDto.getOrderCode() + "", 1));
			messageContentCreateDtos.add(new MessageContentCreateDto("车辆名称", goodsName, 2));
			messageContentCreateDtos.add(new MessageContentCreateDto("车牌号", carDto.getLicencePlate(), 3));
			messageContentCreateDtos.add(new MessageContentCreateDto("还车时间",
					DateUtil.formatDate(LocalDateTime.now(), "yyyy年MM月dd日  HH:mm:ss"), 4));

			messageCenterCreateBizDto.setMessageCenterCreateDto(messageCenterCreateDto);
			messageCenterCreateBizDto.setMessageContentCreateDtoList(messageContentCreateDtos);
			messageCenterBizService.careteMessageCenterBiz(messageCenterCreateBizDto);

			// 发送提醒给业务人员
			pushMsgToService(orderSubscribeDto.getOrderCode(), carDto);

		} catch (Exception e) {
			String msg = "还车(" + orderSubscribeDto.getOrderCode() + ")完成发送消息异常：";
			logger.error(msg, e);
		}
	}

	private void pushMsg(OrderExclusivelBizDto orderExclusivelBizDto, CarDto carDto, StoreBizDto store) {
		try {
			// 查询用户信息
			UserDto userDto = userService.getUser(orderExclusivelBizDto.getUserId());
			JSONObject json = new JSONObject();
			// 订单
			json.put("order", orderExclusivelBizDto.getOrderCode());
			// 发送短信
			try {
				smsBizService.sendMessage(userDto.getPhone(), SmsTemplateEnum.ORDER_RETURN_SMS.getValue(),
						json.toJSONString(), null);
			} catch (Exception e) {
				logger.error("还车(" + orderExclusivelBizDto.getOrderCode() + ")完成发送短信异常", e);
			}
			// 发送推送
			MessageTemplateDto messageTemplateDto = null;
			try {
				messageTemplateDto = messageTemplateService.getByKey("push_return_car_success");
				String body = messageTemplateDto.getBody().replace("${orderCode}",
						orderExclusivelBizDto.getOrderCode() + "");
				// 推送
				NotifyPushCreateDto notifyPush = new NotifyPushCreateDto(Arrays.asList(userDto.getPhone()),
						messageTemplateDto.getSubject(), messageTemplateDto.getSubject(), body, body, null, "");
				notifyPushService.notifyPushByAlias(notifyPush);
			} catch (Exception e) {
				logger.error("还车(" + orderExclusivelBizDto.getOrderCode() + ")完成发送短信异常", e);
			}

			// 查询车型信息
			VehicleNameBizDto vehicleName = vehicleBizService.getCarByModel(orderExclusivelBizDto.getVehicleId());
			String goodsName = vehicleName.getModelName() + " "
					+ (orderExclusivelBizDto.getIsBuyback() ? "回购" : "不回购") + " / "
					+ orderExclusivelBizDto.getTransportTime() + "期 / "
					+ (OrderPaymentMethodEnum.INSTALLMENT.equals(orderExclusivelBizDto.getPaymentMethod()) ? "月付"
							: orderExclusivelBizDto.getPaymentMethod().getName());

			// 保存消息
			MessageCenterCreateBizDto messageCenterCreateBizDto = new MessageCenterCreateBizDto();
			MessageCenterCreateDto messageCenterCreateDto = new MessageCenterCreateDto();
			messageCenterCreateDto.setUserId(userDto.getId());
			messageCenterCreateDto.setTitle("还车成功通知");
			messageCenterCreateDto.setMessage("您的订单车辆已归还，祝您生活愉快！");
			messageCenterCreateDto.setType(MessageCenterTypeEnum.CARRIAGE_SUCCESS_NOTICE.getValue());
			messageCenterCreateDto.setStatus(MessageCenterStatusEnum.UNREAD.getValue());
			List<MessageContentCreateDto> messageContentCreateDtos = new ArrayList<>();
			messageContentCreateDtos
					.add(new MessageContentCreateDto("订单号", orderExclusivelBizDto.getOrderCode() + "", 1));
			messageContentCreateDtos.add(new MessageContentCreateDto("车辆名称", goodsName, 2));
			messageContentCreateDtos.add(new MessageContentCreateDto("车牌号", carDto.getLicencePlate(), 3));
			messageContentCreateDtos.add(new MessageContentCreateDto("还车时间",
					DateUtil.formatDate(LocalDateTime.now(), "yyyy年MM月dd日  HH:mm:ss"), 4));

			messageCenterCreateBizDto.setMessageCenterCreateDto(messageCenterCreateDto);
			messageCenterCreateBizDto.setMessageContentCreateDtoList(messageContentCreateDtos);
			messageCenterBizService.careteMessageCenterBiz(messageCenterCreateBizDto);

			// 发送提醒给业务人员
			pushMsgToService(orderExclusivelBizDto.getOrderCode(), carDto);

		} catch (Exception e) {
			String msg = "还车(" + orderExclusivelBizDto.getOrderCode() + ")完成发送消息异常：";
			logger.error(msg, e);
		}
	}

	private void pushMsgToService(Long orderCode, CarDto carDto) {
		try {
			List<RiskEmailDto> riskEmailDtos = riskEmailService.getByType(RiskEmailTypeEnum.PDI_CHECK.getValue(), null);
			if (riskEmailDtos == null || riskEmailDtos.isEmpty()) {
				return;
			}

			List<String> emailRecipients = new ArrayList<>();
			List<String> emailCopys = new ArrayList<>();
			String dingTalkUrl = null;
			for (RiskEmailDto riskEmailDto : riskEmailDtos) {
				if (riskEmailDto.getReceiveType() == RiskEmailReceiveTypeEnum.EMAIL_RECIPIENT.getValue()) {
					emailRecipients.add(riskEmailDto.getEmail());
				} else if (riskEmailDto.getReceiveType() == RiskEmailReceiveTypeEnum.EMAIL_COPY.getValue()) {
					emailCopys.add(riskEmailDto.getEmail());
				} else if (riskEmailDto.getReceiveType() == RiskEmailReceiveTypeEnum.DINGTALK_WEBHOOK.getValue()) {
					dingTalkUrl = riskEmailDto.getEmail();
				}
			}

			if (!emailRecipients.isEmpty()) {
				// 发送邮件
				String subject = "PDI检验提醒";
				String content = "亲，有一PDI待检验车辆（" + carDto.getLicencePlate() + "），请尽快登录系统跟进处理。";
				EmailUtil.sendMail(EMAIL_ACCOUNT, EMAIL_PASSWORD, subject, content, emailRecipients,
						(emailCopys.isEmpty() ? null : emailCopys));
			}
			if (StringUtils.isNotBlank(dingTalkUrl)) {
				String content = "PDI待检验车辆（" + carDto.getLicencePlate() + "），请尽快登录系统跟进处理。";
				// 发送钉钉
				DingTalkUtil.execute(dingTalkUrl, content);
			}
		} catch (Exception e) {
			String msg = "订单(" + orderCode + ")PDI待检验车辆发送信息给客服异常：";
			logger.error(msg, e);
		}
	}

	private boolean checkModifyCar(ReturnCarModifyVo modifyVo, CarDto carDto, StoreBizDto store,
			CarCheckTypeEnum carCheckType) {
		// 检验车辆是否在门店围栏中，并获取围栏id
		// if (!iovFenceService.getInfence(store.getFenceId(), carDto.getVin()))
		// {
		// logger.error("[checkModifyCar]车辆({})不在门店({})围栏({})中",
		// modifyVo.getCarId(), store.getStoreId(),
		// store.getFenceId());
		// return false;
		// }

		Integer fenceId = getInFenceId(store.getStoreId(), carDto.getVin());
		if (fenceId == null || fenceId <= 0) {
			logger.error("[checkModifyCar]车辆({})不在门店({})围栏中", modifyVo.getCarId(), store.getStoreId());
			return false;
		}

		// 修改车辆信息、保存车辆交接单信息、新增pdi检验信息
		try {
			if (!carBizService
					.modifyReturnCar(Convert.toReturnCarModifyBizDto(modifyVo, carDto, store, carCheckType))) {
				logger.error("[checkModifyCar]车辆还车({})修改失败", modifyVo.getCarId());
				return false;
			}
		} catch (Exception e) {
			logger.error("[checkModifyCar]车辆还车(" + modifyVo.getCarId() + ")修改异常", e);
			return false;
		}
		// 库存状态改为不可租，并绑定围栏id
		try {
			if (!stockCarService.modifyCarStatusAndFenceId(modifyVo.getCarId(),
					StockCarCarStatusEnum.NOT_RENT.getValue(), fenceId)) {
				logger.error("[checkModifyCar]车辆({})还车修改库存状态失败", modifyVo.getCarId());
				DingTalkUtil.exceptionSend(ACTIVE_EXPLAIN + "车辆(" + modifyVo.getCarId() + ")修改库存状态失败");
			}
		} catch (Exception e) {
			logger.error("[checkModifyCar]车辆(" + modifyVo.getCarId() + ")还车修改库存状态异常", e);
			DingTalkUtil.exceptionSend(ACTIVE_EXPLAIN + "车辆(" + modifyVo.getCarId() + ")修改库存状态异常");
		}
		// 修改成功，绑定围栏
		try {
			IovFenceBindingCreateDto createDto = new IovFenceBindingCreateDto();
			createDto.setListVin(Arrays.asList(carDto.getVin()));
			createDto.setFenceId(Long.valueOf(fenceId));
			if (!iovFenceService.addBindingFence(createDto)) {
				logger.error("[checkModifyCar]车辆({})还车绑定门店({})围栏({})失败", modifyVo.getCarId(), store.getStoreId(),
						fenceId);
				DingTalkUtil.exceptionSend(ACTIVE_EXPLAIN + "车辆(" + modifyVo.getCarId() + ")还车绑定门店("
						+ store.getStoreId() + ")围栏(" + fenceId + ")失败");
			}
		} catch (Exception e) {
			logger.error("[checkModifyCar]车辆(" + modifyVo.getCarId() + ")还车绑定门店(" + store.getStoreId() + ")围栏("
					+ store.getFenceId() + ")异常", e);
			DingTalkUtil.exceptionSend(ACTIVE_EXPLAIN + "车辆(" + modifyVo.getCarId() + ")还车绑定门店(" + store.getStoreId()
					+ ")围栏(" + store.getFenceId() + ")异常");
		}

		try {
			maintenanceService.updateMaintenanceReturnCar(carDto.getId());
		} catch (Exception e) {
			logger.error("[checkModifyCar]车辆(" + modifyVo.getCarId() + ")还车车辆(" + carDto.getId() + ")修改保养异常", e);
		}

		return true;
	}

    /**
     * 获取车辆所在门店围栏id
     *
     * @param storeId
     * @param vin
     * @return
     */
    private Integer getInFenceId(Integer storeId, String vin) {
        List<Integer> fenceIdList = fenceStoreStockService.getFenceByStoreId(storeId, FenceStoreStockTypeEnum.STORE);
        if (null == fenceIdList || fenceIdList.size() < 1) {
            return -1;
        }
        return iovFenceService.getInFenceId(fenceIdList, vin);
    }

	/**
	 * 查询订单还车结果
	 * 
	 * @param orderCode
	 *            订单号
	 * @return
	 */
	@Override
	public ReturnCarResultVo getReturnCarResult(Long orderCode) {
		ReturnCarResultVo result = new ReturnCarResultVo();
		OrderBizDto order = orderBizService.getOrder(orderCode);
		if (order == null) {
			logger.error("[modifyReturnCar]订单({})还车失败，订单不存在", orderCode);
			result.failure("还车失败！");
			return result;
		}
		if (OrderTypeEnum.SUBSCRIBE.equals(order.getType())) {
			// 订阅订单还车,查询订单信息
			OrderSubscribeBizDto orderSubscribeDto = (OrderSubscribeBizDto) order;
			// 验证订单信息
			if (orderSubscribeDto.getIsHaveSuborder()) {
				logger.error("[getReturnCarResult]订单({})还车失败，存在续订单", orderCode);
				result.failure("还车失败！");
				return result;
			} else if (OrderStatusConst.RETURN_SUBSCRIBE_STATUS.contains(orderSubscribeDto.getOrderStatus())) {
				result.success("还车完成，祝您生活愉快！");
				return result;
			} else {
				logger.error("[getReturnCarResult]订单({})还车失败，状态({})异常", orderCode, orderSubscribeDto.getOrderStatus());
				result.failure("还车失败！");
				return result;
			}
		} else if (OrderTypeEnum.EXCLUSIVEL.equals(order.getType())) {
			// 专属订单还车
			OrderExclusivelBizDto orderExclusivelBizDto = (OrderExclusivelBizDto) order;
			if (orderExclusivelBizDto.getCarId() == null || orderExclusivelBizDto.getCarId() <= 0) {
				logger.error("[getReturnCarResult]订单({})还车失败，未提车", orderCode);
				result.failure("还车失败！");
				return result;
			} else if (OrderStatusConst.RENEGE_EXCLUSIVEL_STATUS.contains(orderExclusivelBizDto.getOrderStatus())) {
				result.success("退租车辆归还成功，祝您生活愉快！");
				result.setExplain(
						"为保证您的剩余钱款快速到账，请协同工作人员和车务人员对车辆质损评估结果进行线下确认，在您确认后将进入退租的退款结算流程，扫描下方二维码上传退款账号的信息。或在茉莉科技APP进行退租账号信息的填写。");
				return result;
			} else {
				logger.error("[getReturnCarResult]订单({})还车失败，状态({})异常", orderCode,
						orderExclusivelBizDto.getOrderStatus());
				result.failure("还车失败！");
				return result;
			}
		} else {
			logger.error("[getReturnCarResult]订单({})还车失败，订单类型({})异常", orderCode, order.getType());
			result.failure("还车失败！");
			return result;
		}
	}
}
